﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using ArithCollect;
using System.Linq;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Text;
using System.Web.Razor;
using System.IO;

namespace UnitTestProject1 {
    namespace Test11 {
        class C11<T> {
            public class Node {
                public Node next;
                public T data;
                public Node(T data) {
                    this.data = data;
                }
            }
            Node head;
            public void Append(T data) {
                var x2 = new Node(data);
                if (head == null) {
                    head = x2; return;
                }
                var x = head;
                while (x.next != null) {
                    x = x.next;
                }
                x.next = x2;
            }
            public IEnumerable<T> Items { get { var x = head; while (x != null) { yield return x.data; x = x.next; } } }
        }
        [TestClass]
        public class C1 {
            [TestMethod]
            public void m11() {
                var x = new C11<int>();
                x.Append(1); x.Append(2); x.Append(3); x.Append(4);
                x.Append(5); x.Append(6); x.Append(7); x.Append(8);
                foreach (var item in x.Items) {
                    Console.Write("{0},", item);
                }
                Console.WriteLine();
                foreach (var item in x.Items) {
                    Console.Write("{0},",item);
                }
            }
        }
    }
    /*关于图的边*/
    namespace Test10 {
        [TestClass]
        public class C1 {
            [TestMethod]
            public void m12() {
                var g = new Graph<string>();
                var x = new Tople<int, float>[][] {
                    new Tople<int,float>[] { new Tople<int,float>(1,4f) ,new Tople<int,float>(2,2f) ,new Tople<int,float>(3,3f) }, //顶点1
                    new Tople<int,float>[] { new Tople<int,float>(0,4f) ,new Tople<int,float>(3,4f) ,new Tople<int,float>(4,4f) ,new Tople<int,float>(5,3f) }, //顶点2
                    new Tople<int,float>[] { new Tople<int,float>(0,2f) ,new Tople<int,float>(3,5f) ,new Tople<int,float>(4,1f),new Tople<int,float>(5,2f) }, //顶点3
                    new Tople<int,float>[] { new Tople<int,float>(0,3f) ,new Tople<int,float>(1,4f) ,new Tople<int,float>(2,5f)}, //顶点4
                    new Tople<int,float>[] { new Tople<int,float>(1,4f), new Tople<int,float>(2,1f),new Tople<int,float>(5,4f) } ,//顶点5
                    new Tople<int,float>[] { new Tople<int,float>(1,3f), new Tople<int,float>(2,2f),new Tople<int,float>(4,4f) } //顶点6
                };
                g.AddRange(x);
                var x2 = g.Kruscal();
                foreach (var item in x2) {
                    Console.WriteLine("{0}-{1}:{2}", item.Item1, item.Item2, item.Item3);
                }
            }
            [TestMethod]
            public void m11() {
                var g = new Graph<string>();
                var x = new Tople<int, float>[][] {
                    new Tople<int,float>[] { new Tople<int,float>(1,4f) ,new Tople<int,float>(2,2f) ,new Tople<int,float>(3,3f) }, //顶点1
                    new Tople<int,float>[] { new Tople<int,float>(0,4f) ,new Tople<int,float>(3,4f) ,new Tople<int,float>(4,4f) ,new Tople<int,float>(5,3f) }, //顶点2
                    new Tople<int,float>[] { new Tople<int,float>(0,2f) ,new Tople<int,float>(3,5f) ,new Tople<int,float>(4,1f),new Tople<int,float>(5,2f) }, //顶点3
                    new Tople<int,float>[] { new Tople<int,float>(0,3f) ,new Tople<int,float>(1,4f) ,new Tople<int,float>(2,5f)}, //顶点4
                    new Tople<int,float>[] { new Tople<int,float>(1,4f), new Tople<int,float>(2,1f),new Tople<int,float>(5,4f) } ,//顶点5
                    new Tople<int,float>[] { new Tople<int,float>(1,3f), new Tople<int,float>(2,2f),new Tople<int,float>(4,4f) } //顶点6
                };
                g.AddRange(x);
                var x2=g.Prim();
                foreach (var item in x2) {
                    Console.WriteLine("{0}-{1}:{2}",item.Item1,item.Item2,item.Item3);
                }
            }
            [TestMethod]
            public void M1() {
                var g = new Graph<int>();
                g.Add(1);
                g.Add(1);
                g.Add(1);
                g.Add(1);
                g.Add(1);
                g.Add(1);
                //
                g.SetAssociateByIndex(0, 1, 2);
                g.SetAssociateByIndex(1, 2, 3, 4);
                g.SetAssociateByIndex(2, 0, 3);
                g.SetAssociateByIndex(3, 1, 4, 5, 3);
                g.SetAssociateByIndex(4, 5, 2);
                g.SetAssociateByIndex(5, 0);
                //
                g.InitialUnitEdges();
                g.SetEdge(0, 1, 2.2f);
                g.SetEdge(0, 2, 3.2f);
            }
            /*public Edge[] Kruskal()
                {
                  // This will store the resultant MST
                  Edge[] mst = new Edge[VertexCount - 1];
                
                  // Step 1: Sort all the edges in non-decreasing order of their weight
                  // If we are not allowed to change the given graph, we can create a copy of
                  // array of edges
                  var sortedEdges = this.Edges.OrderBy(t => t.Weight);
                  var enumerator = sortedEdges.GetEnumerator();
                
                  // Allocate memory for creating V ssubsets
                  // Create V subsets with single elements
                  Subset[] subsets = new Subset[VertexCount];
                  for (int i = 0; i < subsets.Length; i++)
                  {
                    subsets[i] = new Subset();
                    subsets[i].Parent = i;
                    subsets[i].Rank = 0;
                  }
                
                  // Number of edges to be taken is equal to V-1
                  int e = 0;
                  while (e < VertexCount - 1)
                  {
                    // Step 2: Pick the smallest edge. And increment the index
                    // for next iteration
                    Edge nextEdge;
                    if (enumerator.MoveNext())
                    {
                      nextEdge = enumerator.Current;
                
                      int x = Find(subsets, nextEdge.Begin);
                      int y = Find(subsets, nextEdge.End);
                
                      // If including this edge does't cause cycle, include it
                      // in result and increment the index of result for next edge
                      if (x != y)
                      {
                        mst[e++] = nextEdge;
                        Union(subsets, x, y);
                      }
                      else
                      {
                        // Else discard the nextEdge
                      }
                    }
                  }                
                  return mst;
                }
*/
        }
    }
    /*
    * 输入两个整数 n 和 m，从数列1，2，3.......n 中 随意取几个数,
        使其和等于 m ,要求将其中所有的可能组合列出来.
     * ----
     * 1、对于一个整数矩阵，存在一种运算，对矩阵中任意元素加一时，需要其相邻（上下左右）
        某一个元素也加一，现给出一正数矩阵，判断其是否能够由一个全零矩阵经过上述运算得到。
        2、.一个整数数组，长度为n，将其分为m份，使各份的和相等，求m的最大值
        比如{3，2，4，3，6} 可以分成{3，2，4，3，6} m=1; 
        {3,6}{2,4,3} m=2
        {3,3}{2,4}{6} m=3 所以m的最大值为3
        3、.搜狐：
        4对括号可以有多少种匹配排列方式？比如两对括号可以有两种：（）（）和（（））
        4、创新工场：
        求一个数组的最长递减子序列 比如{9，4，3，2，5，4，3，2}的
        最长递减子序列为{9，5，4，3，2}
        5、微软：
        一个数组是由一个递减数列左移若干位形成的，比如{4，3，2，1，6，5}
        是由{6，5，4，3，2，1}左移两位形成的，在这种数组中查找某一个数。
        在此，只重点给出第4题，最长递减子序列的答案：
        4、创新工场：最长递减子序列
        求一个数组的最长递减子序列 比如{9，4，3，2，5，4，3，2}的
        最长递减子序列为{9，5，4，3，2}
     * http://blog.csdn.net/v_JULY_v/article/details/6171539
     */
    namespace Test9 {
        class C1 {
            internal IEnumerable<List<int>> Find_Factor(int sum, int n) {
                var list1 = n.AdagunSet().ToList();
                return null;
            }
        }
        [TestClass]
        public class C2 {
            [TestMethod]
            public void Main1() {
                int[] items = new int[] { 4, 2, 6, 3, 1, 2, 5 };
                //用来记录序列长队最大值的数组，index + 1就是序列的长度
                int[] maxValues = new int[items.Length];
                int maxLength = 1;
                maxValues[0] = items[0];
                for (int i = 1; i < items.Length; i++) {
                    //二分查找对应的最长序列
                    int lengthIndex = Array.BinarySearch<int>(maxValues, 0, maxLength, items[i]);
                    //针对于.Net里面的BinarySearch的特殊处理，不用理会
                    if (lengthIndex < 0)
                        lengthIndex = -lengthIndex - 1;
                    if (lengthIndex + 1 > maxLength)
                        maxLength = lengthIndex + 1;
                    maxValues[lengthIndex] = items[i];
                }
                Console.WriteLine(maxLength);
            }
        }
    }
    /*二叉查找树*/
    namespace Test8 {
        [TestClass]
        public class C1 {
            [TestMethod]
            public void M1() {
                var x = 12.AdagunSet().ToArray();
                x.Shuffle();
                var bt = new BinFinderTree<int>();
                bt.LoadData(x);
                Console.WriteLine("原数据");
                foreach (var item in x) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine("{0}左中充遍历数据为：", Environment.NewLine);
                foreach (var item in bt) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine("{0}右中充遍历数据为：", Environment.NewLine);
                foreach (var item in bt.Query(bt.Root, TreeTraversalType.Un)) {
                    Console.Write("{0} ", item);
                }
            }
        }
    }
    /*排序改进与性能分析*/
    namespace Test7 {
        [TestClass]
        public class C2 {
            #region 快排
            ///<summary>
            /// 最简洁的快速排序
            ///</summary>
            ///<typeparam name="T">可比较的类型</typeparam>
            ///<param name="array">待排序数组</param>
            ///<param name="start">数组起始索引</param>
            ///<param name="end">数组末尾索引</param>
            internal static void QuickSort<T>(T[] array, int start, int end) where T : IComparable<T> {
                var left = start;
                var right = end;
                var middle = array[start];
                while (true) {
                    while (array[right].CompareTo(middle) > 0) right--;
                    if (right == left) break;
                    Swap(array, left++, right);
                    while (array[left].CompareTo(middle) < 0) left++;
                    if (right == left) break;
                    Swap(array, left, right--);
                }

                if (left - start > 1) QuickSort(array, start, left - 1); //如子区间块长大于1，则继续对区间排序
                if (end - left > 1) QuickSort(array, left + 1, end);
            }

            ///<summary>
            /// 交换数组中两个索引对应的元素
            ///</summary>
            static void Swap<T>(T[] array, int n1, int n2) {
                var temp = array[n1];
                array[n1] = array[n2];
                array[n2] = temp;
            }
            internal static void QuickSort2(int[] array, int start, int end) {
                var left = start;
                var right = end;
                var middle = array[start];
                while (true) {
                    while (array[right].CompareTo(middle) > 0) right--;
                    if (right == left) break;
                    Swap(array, left++, right);
                    while (array[left].CompareTo(middle) < 0) left++;
                    if (right == left) break;
                    Swap(array, left, right--);
                }

                if (left - start > 1) QuickSort(array, start, left - 1); //如子区间块长大于1，则继续对区间排序
                if (end - left > 1) QuickSort(array, left + 1, end);
            }

            ///<summary>
            /// 交换数组中两个索引对应的元素
            ///</summary>
            static void Swap(int[] array, int n1, int n2) {
                var temp = array[n1];
                array[n1] = array[n2];
                array[n2] = temp;
            }
            #endregion
            public void SortHeap2(int[] data) {
                var len = data.Length; var len1 = len + 2;
                var temps = new int[len1];
                for (int i = 0; i < len; i++) {
                    Enheap(temps, data[i], i);
                }
                //temps = temps.CutOut(1, len1).intoArray();
                for (int i = 0; i < len; i++) {
                    data[i] = Deheap(temps, len - i);
                }
            }
            static void Enheap(int[] temps, int item, int p) {
                if (p == 0) {
                    temps[1] = item;
                } else {
                    var len = p + 1;
                    var poss = len.GetLengthHigh().ToArray();
                    var len2 = poss.Length;
                    var mark = 0;
                    for (int i = 1; i < len2; i++) {
                        mark = i - 1;
                        if (item < temps[poss[i]]) { temps[poss[mark]] = temps[poss[i]]; continue; }
                        break;
                    }
                    if (mark == len2 - 2 && temps[poss[mark]] == temps[poss[mark + 1]]) {
                        temps[1] = item;//换根节点
                    } else {
                        temps[poss[mark]] = item;
                    }
                }
            }
            /// <summary>  
            /// Remove the top item from the heap  
            /// </summary>  
            static int Deheap(int[] temps, int len) {
                var p = 1;
                var temp = temps[p];
                while (2 * p < len) {
                    if (2 * p <= len && 2 * p + 1 <= len) {
                        if (temps[2 * p] > temps[2 * p + 1]) {
                            var temp2 = temps[2 * p + 1];
                            if (temps[len] < temp2) {
                                temps[p] = temps[len]; goto step2;
                            } else {
                                temps[p] = temp2;
                            }
                            p = 2 * p + 1;
                        } else {
                            var temp2 = temps[2 * p];
                            if (temps[len] < temp2) {
                                temps[p] = temps[len]; goto step2;
                            } else {
                                temps[p] = temp2;
                            }
                            p *= 2;
                        }
                    } else if (2 * p <= len) {
                        var temp2 = temps[2 * p];
                        if (temps[len] < temp2) {
                            temps[p] = temps[len]; goto step2;
                        } else {
                            temps[p] = temp2;
                        }
                        p *= 2;
                    }
                }
                temps[p] = temps[len];
            step2:
                return temp;
            }
            #region 网上堆排序
            /// <summary>
            /// 小根堆排序
            /// </summary>
            /// <param name="dblArray"></param>
            /// <param name="StartIndex"></param>
            /// <returns></returns>
            public void HeapSort(int[] dblArray) {
                for (int i = dblArray.Length - 1; i >= 0; i--) {
                    if (2 * i + 1 < dblArray.Length) {
                        int MinChildrenIndex = 2 * i + 1;
                        //比较左子树和右子树，记录最小值的Index
                        if (2 * i + 2 < dblArray.Length) {
                            if (dblArray[2 * i + 1] > dblArray[2 * i + 2])
                                MinChildrenIndex = 2 * i + 2;
                        }
                        if (dblArray[i] > dblArray[MinChildrenIndex]) {
                            ExchageValue(ref dblArray[i], ref dblArray[MinChildrenIndex]);
                            NodeSort(ref dblArray, MinChildrenIndex);
                        }
                    }
                }
            }
            /// <summary>
            /// 节点排序
            /// </summary>
            /// <param name="dblArray"></param>
            /// <param name="StartIndex"></param>
            private void NodeSort(ref int[] dblArray, int StartIndex) {
                while (2 * StartIndex + 1 < dblArray.Length) {
                    int MinChildrenIndex = 2 * StartIndex + 1;
                    if (2 * StartIndex + 2 < dblArray.Length) {
                        if (dblArray[2 * StartIndex + 1] > dblArray[2 * StartIndex + 2]) {
                            MinChildrenIndex = 2 * StartIndex + 2;
                        }
                    }
                    if (dblArray[StartIndex] > dblArray[MinChildrenIndex]) {
                        ExchageValue(ref dblArray[StartIndex], ref dblArray[MinChildrenIndex]);
                        StartIndex = MinChildrenIndex;
                    }
                }
            }
            /// <summary>
            /// 交换值
            /// </summary>
            /// <param name="A"></param>
            /// <param name="B"></param>
            private void ExchageValue(ref int A, ref int B) {
                var Temp = A;
                A = B;
                B = Temp;
            }
            #endregion
            #region 加强版插入排序
            public void SortSuperInsert(int[] data) {
                var count = data.Length;
                for (int i = 1; i < count; i++) {
                    var t = data[i];
                    var j = i;
                    while (data[j] > t) {
                        data[j] = data[--j];
                    }
                    data[j] = t;
                }
            }
            #endregion
            public static void ShellSort(int[] array) {
                int point = array.Length / 2;
                while (point > 0) {
                    for (int i = 0; i < point; i++) {
                        for (int j = i; j < array.Length; j += point) {
                            for (int k = i; k < j; k += point) {
                                if (array[k] > array[j]) {
                                    int insertValue = array[j];
                                    for (int t = j; t > k; t -= point) {
                                        array[t] = array[t - point];
                                    }
                                    array[k] = insertValue;
                                }
                                continue;
                            }
                        }
                    }
                    point = point / 2;
                }
            }
            [TestMethod]
            public void M_SortExeableTest() {
                var len = 11051;
                var x2 = len.AdagunSet().ToArray();
                x2.Shuffle();
                Console.WriteLine("源数据：");
                //foreach (var item in x2) {
                //    Console.Write("{0} ", item);
                //}
                var x22 = new int[len];
                var x23 = new int[len];
                var x24 = new int[len];
                var x25 = new int[len];
                var x26 = new int[len];
                var x27 = new int[len];
                var x28 = new int[len];
                var x29 = new int[len];
                var x30 = new int[len];
                x2.CopyTo(x22, 0);
                x2.CopyTo(x23, 0);
                x2.CopyTo(x24, 0);
                x2.CopyTo(x25, 0);
                x2.CopyTo(x26, 0);
                x2.CopyTo(x27, 0);
                x2.CopyTo(x28, 0);
                x2.CopyTo(x29, 0);
                x2.CopyTo(x30, 0);
                var x3 = new System.Diagnostics.Stopwatch();
                var x33 = new System.Diagnostics.Stopwatch();
                var x34 = new System.Diagnostics.Stopwatch();
                var x35 = new System.Diagnostics.Stopwatch();
                var x36 = new System.Diagnostics.Stopwatch();
                var x37 = new System.Diagnostics.Stopwatch();
                var x38 = new System.Diagnostics.Stopwatch();
                var x39 = new System.Diagnostics.Stopwatch();
                var x40 = new System.Diagnostics.Stopwatch();
                x3.Start();
                x2.SortSelect();
                x3.Stop();
                x33.Start();
                x22.SortSelectD();
                x33.Stop();
                x34.Start();
                x23.SortBubble();
                x34.Stop();
                x35.Start();
                x24.SortInsert();
                x35.Stop();
                x36.Start();
                x25.SortQuick();
                x36.Stop();
                x37.Start();
                x26.SortOddEven();
                x37.Stop();
                x38.Start();
                x27.SortCocktail();
                x38.Stop();
                x39.Start();
                ShellSort(x28);
                //x28.SortHeap();
                x39.Stop();
                x40.Start();
                QuickSort2(x30, 0, x30.Length - 1);
                x40.Stop();
                Console.WriteLine();
                //Console.WriteLine("单选择排序结果：");
                //foreach (var item in x2) {
                //    Console.Write("{0} ", item);
                //}
                //Console.WriteLine();
                //Console.WriteLine("双选择排序结果：");
                //foreach (var item in x22) {
                //    Console.Write("{0} ", item);
                //}
                //Console.WriteLine();
                //Console.WriteLine("冒泡排序结果：");
                //foreach (var item in x23) {
                //    Console.Write("{0} ", item);
                //}
                //Console.WriteLine();
                //Console.WriteLine("插入排序结果：");
                //foreach (var item in x24) {
                //    Console.Write("{0} ", item);
                //}
                //Console.WriteLine();
                //Console.WriteLine("快速排序结果：");
                //foreach (var item in x25) {
                //    Console.Write("{0} ", item);
                //}
                //Console.WriteLine();
                //Console.WriteLine("奇偶排序结果：");
                //foreach (var item in x26) {
                //    Console.Write("{0} ", item);
                //}
                //Console.WriteLine();
                //Console.WriteLine("鸡尾酒排序结果：");
                //foreach (var item in x27) {
                //    Console.Write("{0} ", item);
                //}
                //Console.WriteLine();
                //Console.WriteLine("堆排序结果：");
                //foreach (var item in x28) {
                //    Console.Write("{0} ", item);
                //}
                //Console.WriteLine();
                //Console.WriteLine("堆(网上代码)排序结果：");
                //foreach (var item in x30) {
                //    Console.Write("{0} ", item);
                //}
                Console.WriteLine();
                Console.WriteLine("单选择排序耗时:{0}", x3.Elapsed.TotalMilliseconds);
                Console.WriteLine("双选择排序耗时:{0}", x33.Elapsed.TotalMilliseconds);
                Console.WriteLine("冒泡排序耗时:{0}", x34.Elapsed.TotalMilliseconds);
                Console.WriteLine("插入排序耗时:{0}", x35.Elapsed.TotalMilliseconds);
                Console.WriteLine("快速排序耗时:{0}", x36.Elapsed.TotalMilliseconds);
                Console.WriteLine("奇偶排序耗时:{0}", x37.Elapsed.TotalMilliseconds);
                Console.WriteLine("鸡尾酒排序耗时:{0}", x38.Elapsed.TotalMilliseconds);
                Console.WriteLine("堆排序耗时:{0}", x39.Elapsed.TotalMilliseconds);
                Console.WriteLine("快排(网上代码)排序耗时:{0}", x40.Elapsed.TotalMilliseconds);
            }
        }
        [TestClass]
        public class C1 {
            [TestMethod]
            public void M1() {
                var len = 1105;
                var x2 = len.AdagunSet().ToArray();
                x2.Shuffle();
                Console.WriteLine("源数据：");
                foreach (var item in x2) {
                    Console.Write("{0} ", item);
                }
                var x22 = new int[len];
                var x23 = new int[len];
                var x24 = new int[len];
                var x25 = new int[len];
                var x26 = new int[len];
                var x27 = new int[len];
                var x28 = new int[len];
                x2.CopyTo(x22, 0);
                x2.CopyTo(x23, 0);
                x2.CopyTo(x24, 0);
                x2.CopyTo(x25, 0);
                x2.CopyTo(x26, 0);
                x2.CopyTo(x27, 0);
                x2.CopyTo(x28, 0);
                var x3 = new System.Diagnostics.Stopwatch();
                var x33 = new System.Diagnostics.Stopwatch();
                var x34 = new System.Diagnostics.Stopwatch();
                var x35 = new System.Diagnostics.Stopwatch();
                var x36 = new System.Diagnostics.Stopwatch();
                var x37 = new System.Diagnostics.Stopwatch();
                var x38 = new System.Diagnostics.Stopwatch();
                var x39 = new System.Diagnostics.Stopwatch();
                var x40 = new System.Diagnostics.Stopwatch();
                x3.Start();
                x2.SortSelect();
                x3.Stop();
                x33.Start();
                x22.SortSelectD();
                x33.Stop();
                x34.Start();
                x23.SortBubble();
                x34.Stop();
                x35.Start();
                x24.SortInsert();
                x35.Stop();
                x36.Start();
                x25.SortQuick();
                x36.Stop();
                x37.Start();
                x26.SortOddEven();
                x37.Stop();
                x38.Start();
                x27.SortCocktail();
                x38.Stop();
                x39.Start();
                x28.SortHeap();
                x39.Stop();
                Console.WriteLine();
                Console.WriteLine("单选择排序结果：");
                foreach (var item in x2) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                Console.WriteLine("双选择排序结果：");
                foreach (var item in x22) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                Console.WriteLine("冒泡排序结果：");
                foreach (var item in x23) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                Console.WriteLine("插入排序结果：");
                foreach (var item in x24) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                Console.WriteLine("快速排序结果：");
                foreach (var item in x25) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                Console.WriteLine("奇偶排序结果：");
                foreach (var item in x26) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                Console.WriteLine("鸡尾酒排序结果：");
                foreach (var item in x27) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                Console.WriteLine("堆排序结果：");
                foreach (var item in x28) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                Console.WriteLine("单选择排序耗时:{0}", x3.Elapsed.TotalMilliseconds);
                Console.WriteLine("双选择排序耗时:{0}", x33.Elapsed.TotalMilliseconds);
                Console.WriteLine("冒泡排序耗时:{0}", x34.Elapsed.TotalMilliseconds);
                Console.WriteLine("插入排序耗时:{0}", x35.Elapsed.TotalMilliseconds);
                Console.WriteLine("快速排序耗时:{0}", x36.Elapsed.TotalMilliseconds);
                Console.WriteLine("奇偶排序耗时:{0}", x37.Elapsed.TotalMilliseconds);
                Console.WriteLine("鸡尾酒排序耗时:{0}", x38.Elapsed.TotalMilliseconds);
                Console.WriteLine("堆排序耗时:{0}", x38.Elapsed.TotalMilliseconds);
            }
        }
    }
    /*关于新的选择排序*/
    namespace Test6 {
        /*归并有序数组*/
        [TestClass]
        public class C3 {
            [TestMethod]
            public void T6() {
                var x = new[] { 1, 3, 5, 9 };
                var x2 = new[] { 8, 15, 16, 29 };
                var x3 = new int[x.Length + x2.Length];
                int i, j; i = j = 0;
                while (i <= x.Length || j <= x2.Length) {

                }
            }
            void T55(int[] data) {
                var len = data.Length;
                var x = len.GetLengthHigh().CutOut(1, len - 1).ToArray();
                var x2 = x.Reverse().ToArray();

            }
            [TestMethod]
            public void T5() {
                var x = 35.GetLengthHigh();
                var x2 = 15.AdagunSet().ToArray();
                var x3 = x2.CutOut(5, 3);
                x2.Shuffle();
                foreach (var item in x3) {
                    Console.Write("{0} ", item);
                }

            }
            [TestMethod]
            public void T3() {
                var x = new[] { 3, 5, 8, 7 };
                var len = x.Length;
                var temp = 2; var index = 1;
                while (temp <= len / 2) {
                    int j, k; j = k = 0;
                    for (int i = 0; i < len; i += temp) {
                        x[i] = x[j] > x[k] ? x[k++] : x[j++];
                    }
                    index++;
                }
            }
            [TestMethod]
            public void T2() {
                ushort a = 30, b = 45;
                var x1 = a.UnrepeatSet(5500).ToArray();
                var x2 = b.UnrepeatSet(5500).ToArray();
                x1.SortQuick();
                x2.SortQuick();
                var len = x1.Length + x2.Length;
                var x3 = new int[len]; int j = 0, k = 0;
                for (int i = 0; i < len - 1; i++) {
                    if (x1[j] == x2[k]) {
                        x3[i + 1] = x3[i] = x1[j]; i++; j++; k++;
                    } else if (k < x2.Length - 1) {
                        k++;
                    } else if (j < x1.Length - 1) {
                        j++;
                    }
                    x3[i] = x1[j] > x2[k] ? x2[k] : x1[j];
                }
                foreach (var item in x2) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                foreach (var item in x1) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                foreach (var item in x3) {
                    Console.Write("{0} ", item);
                }
            }
            [TestMethod]
            public void T1() {
                var x1 = 12.OddSet().ToArray();
                var x2 = 12.EvenSet().ToArray();
                var len = x1.Length + x2.Length;
                var x3 = new int[len]; int j = 0, k = 0;
                for (int i = 0; i < len - 1; i++) {
                    if (x1[j] == x2[k]) {
                        x3[i + 1] = x3[i] = x1[j]; i++; j++; k++;
                    } else if (k < x2.Length - 1 && j < x1.Length - 1) {
                        x3[i] = x1[j] > x2[k] ? x2[k++] : x1[j++];
                    } else if (j == x1.Length - 1 && k < x2.Length - 1) {
                        x3[i] = x1[j] > x2[k] ? x2[k++] : x1[j];
                    } else if (k == x2.Length - 1 && j < x1.Length - 1) {
                        x3[i] = x1[j] > x2[k] ? x2[k] : x1[j++];
                    } else if (k == x2.Length - 1 && j == x1.Length - 1) {
                        x3[i] = x1[j] > x2[k] ? x2[k] : x1[j];
                        x3[i + 1] = x1[j] < x2[k] ? x2[k] : x1[j];
                    }
                }
                //var key = j > k ? k : j;
                //x3[len - 1] = x1[key] > x2[key] ? x1[key] : x1[key];
                foreach (var item in x2) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                foreach (var item in x1) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                foreach (var item in x3) {
                    Console.Write("{0} ", item);
                }
            }
        }
        [TestClass]
        public class C2 {
            /*变长数组copy*/
            [TestMethod]
            public void M2() {
                var x = 12.AdagunSet().ToArray();
                var x2 = new int[13];
                x2[0] = 55;
                x.CopyTo(x2, 1);
                foreach (var item in x2) {
                    Console.WriteLine(item);
                }
            }
            [TestMethod]
            public void M11() {
                var len = 11;
                var x = len.AdagunSet().ToArray();
                /*测试名称: 	M11
                测试结果: 	已通过
                结果 的标准输出: 	
                源数据：
                10 6 5 1 0 9 4 2 3 7 8 
                单选择排序结果：
                0 1 2 3 4 5 6 7 8 9 10 
                双选择排序结果：
                8 1 2 3 4 5 6 7 9 10 0
                */
                x.Shuffle();
                x = new[] { 10, 6, 5, 1, 0, 9, 4, 2, 3, 7, 8 };
                Console.WriteLine("源数据：");
                foreach (var item in x) {
                    Console.Write("{0} ", item);
                }
                var x2 = new int[len];
                x.CopyTo(x2, 0);
                x.SortSelect();
                x2.SortSelectD();
                Console.WriteLine();
                Console.WriteLine("单选择排序结果：");
                foreach (var item in x) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                Console.WriteLine("双选择排序结果：");
                foreach (var item in x2) {
                    Console.Write("{0} ", item);
                }
            }
        }
    }
    /*二叉堆*
     http://www.2cto.com/kf/201311/257177.html */
    namespace Test5 {
        /// <summary>  
        /// The heap's order  
        /// </summary>  
        public enum Order {
            ASC = 0,
            DESC = 1
        }
        /// <summary>  
        /// The BinaryHeap  
        /// </summary>  
        /// <typeparam name="T">The T represent the type of the heap's value</typeparam>  
        public class BinaryHeap<T> where T : IComparable<T> {
            /// <summary>  
            /// The size of the heap  
            /// </summary>  
            public int Size { get; set; }
            private int length;
            public int Length { get { return length; } private set { length = value; } }
            private T[] Items { get; set; }
            private Order Order;
            /// <summary>  
            /// The Cons of the heap  
            /// </summary>  
            /// <param name="size">The default size of the heap</param>  
            /// <param name="order">The order of the heap</param>  
            public BinaryHeap(int size, Order order = Order.ASC) {
                if (size < 1) {
                    throw new Exception("The size should be greater or equal than 1.");
                }
                this.Size = size;
                this.Order = order;
                // We don't need the Items[0], so the actually size is (this.Size + 1),  
                // and we just use the the value of Items[1], Items[2], Items[3]... and so on  
                this.Size++;
                Items = new T[this.Size];
                // Set to 0 represent the heap's length is empty  
                this.length = 0;
            }
            /// <summary>  
            /// Add new item to the heap  
            /// </summary>  
            /// <param name="item"></param>  
            public void Add(T item) {
                if (this.length == 0) {
                    Items[1] = item;
                } else {
                    int len = this.length;
                    if (len >= this.Size) {
                        throw new Exception("The heap is fulfilled, can't add item anymore.");
                    }
                    // Set the new item at the end of this heap  
                    int endPos = len + 1;
                    Items[endPos] = item;
                    // Calculate the new item's parent position  
                    int parentPos = endPos / 2;
                    bool isContinue = true;
                    while (parentPos != 0 && isContinue) {
                        // Compare the new added item and its parent, swap each other if needed  
                        if (Order == Order.ASC) {
                            if (Items[endPos].CompareTo(Items[parentPos]) < 0) {
                                Swap(ref Items[endPos], ref Items[parentPos]);
                                endPos = parentPos;
                                parentPos = endPos / 2;
                            } else {
                                isContinue = false;
                            }
                        } else {
                            if (Items[endPos].CompareTo(Items[parentPos]) > 0) {
                                Swap(ref Items[endPos], ref Items[parentPos]);
                                endPos = parentPos;
                                parentPos = endPos / 2;
                            } else {
                                isContinue = false;
                            }
                        }
                    }
                }
                // After the new item added, set the heap's length added by one  
                this.length++;
            }
            /// <summary>  
            /// Remove the top item from the heap  
            /// </summary>  
            /// <returns>if the order is ASC, return the smallest one, if DESC, return the largest one.</returns>  
            public T Remove() {
                if (this.length == 0) {
                    throw new Exception("The heap is empty");
                }
                // Remove the first item and move the last item to the first  
                T removedItem = Items[1];
                int len = this.length;
                Items[1] = Items[len];
                // After the top item removed, set the heap's length reduced by one  
                this.length--;
                // Get the removing item's childrens's position  
                int currentPos = 1;
                int leftChildPos = currentPos * 2;
                int rightChildPos = currentPos * 2 + 1;
                // Set the while loop continue or not flag  
                bool isContinue = true;
                while ((leftChildPos <= len || rightChildPos <= len) && isContinue) {
                    // Compare the removing item to its childrens, swap each other if needed  
                    if (Order == Order.ASC) {
                        #region Order == BinaryHeap.Order.ASC
                        if (leftChildPos <= len && rightChildPos <= len) {
                            if (Items[leftChildPos].CompareTo(Items[rightChildPos]) < 0 && Items[currentPos].CompareTo(Items[leftChildPos]) >= 0) {
                                Swap(ref Items[currentPos], ref Items[leftChildPos]);
                                currentPos = leftChildPos;
                            } else if (Items[leftChildPos].CompareTo(Items[rightChildPos]) >= 0 && Items[currentPos].CompareTo(Items[rightChildPos]) >= 0) {
                                Swap(ref Items[currentPos], ref Items[rightChildPos]);
                                currentPos = rightChildPos;
                            } else {
                                isContinue = false;
                            }
                        } else if (leftChildPos <= len) {
                            if (Items[currentPos].CompareTo(Items[leftChildPos]) >= 0) {
                                Swap(ref Items[currentPos], ref Items[leftChildPos]);
                                currentPos = leftChildPos;
                            } else {
                                isContinue = false;
                            }
                        } else if (rightChildPos <= len) {
                            if (Items[currentPos].CompareTo(Items[rightChildPos]) >= 0) {
                                Swap(ref Items[currentPos], ref Items[rightChildPos]);
                                currentPos = rightChildPos;
                            } else {
                                isContinue = false;
                            }
                        } else {
                            isContinue = false;
                        }
                        #endregion

                        leftChildPos = currentPos * 2;
                        rightChildPos = currentPos * 2 + 1;
                    } else {
                        #region Order == BinaryHeap.Order.DESC
                        if (leftChildPos <= len && rightChildPos <= len) {
                            if (Items[leftChildPos].CompareTo(Items[rightChildPos]) > 0 && Items[currentPos].CompareTo(Items[leftChildPos]) <= 0) {
                                Swap(ref Items[currentPos], ref Items[leftChildPos]);
                                currentPos = leftChildPos;
                            } else if (Items[leftChildPos].CompareTo(Items[rightChildPos]) <= 0 && Items[currentPos].CompareTo(Items[rightChildPos]) <= 0) {
                                Swap(ref Items[currentPos], ref Items[rightChildPos]);
                                currentPos = rightChildPos;
                            } else {
                                isContinue = false;
                            }
                        } else if (leftChildPos <= len) {
                            if (Items[currentPos].CompareTo(Items[leftChildPos]) <= 0) {
                                Swap(ref Items[currentPos], ref Items[leftChildPos]);
                                currentPos = leftChildPos;
                            } else {
                                isContinue = false;
                            }
                        } else if (rightChildPos <= len) {
                            if (Items[currentPos].CompareTo(Items[rightChildPos]) <= 0) {
                                Swap(ref Items[currentPos], ref Items[rightChildPos]);
                                currentPos = rightChildPos;
                            } else {
                                isContinue = false;
                            }
                        } else {
                            isContinue = false;
                        }
                        #endregion
                        leftChildPos = currentPos * 2;
                        rightChildPos = currentPos * 2 + 1;
                    }
                }
                return removedItem;
            }
            /// <summary>  
            /// Sort the heap  
            /// </summary>  
            /// <returns>Return the sorted heap array</returns>  
            public IEnumerable<T> Sort() {
                if (this.length == 0) {
                    throw new Exception("The heap is empty");
                }
                while (this.length > 0) {
                    yield return Remove();
                }
            }
            #region Private method
            /// <summary>  
            /// Swap each other  
            /// </summary>  
            /// <param name="t1">The first one</param>  
            /// <param name="t2">The second one</param>  
            private void Swap(ref T t1, ref T t2) {
                T temp = t1;
                t1 = t2;
                t2 = temp;
            }
            #endregion
        }
        [TestClass]
        public class C1 {
            [TestMethod]
            public void T4() {
                var x = 256.GetLengthHigh();
                foreach (var item in x) {
                    Console.Write("{0} ", item);
                }
            }
            [TestMethod]
            public void M2() {
                var x2 = (ushort)new Random().Next(20, 40);
                var x = x2.UnrepeatSet(500, 20).ToArray();
                /*测试名称: 	M2
测试结果: 	已通过
结果 的标准输出: 	
数据源:
187 330 27 269 106 448 426 390 131 35 158 293 50 111 412 260 478 305 325 226 31 303 49 469 59 256 
二叉堆排序:
27 31 35 49 50 59 106 111 131 158 187 226 256 260 269 293 305 325 330 390 303 412 426 448 469 478

*/
                x = new[] { 187, 330, 27, 269, 106, 448, 426, 390, 131, 35, 158, 293, 50, 111, 412, 260, 478, 305, 325, 226, 31, 303, 49, 469, 59, 256 };
                Console.WriteLine("数据源:");
                foreach (var item in x) {
                    Console.Write("{0} ", item);
                }
                x.SortHeap();
                Console.WriteLine();
                Console.WriteLine("二叉堆排序:");
                foreach (var item in x) {
                    Console.Write("{0} ", item);
                }
            }
            [TestMethod]
            public void M1() {
                var bh = new BinaryHeap<int>(8);
                ushort x2 = 8;
                var x = x2.UnrepeatSet(50, 20);
                x = new[] { 23, 47, 37, 31, 48, 21, 45, 39 };
                foreach (var item in x) {
                    bh.Add(item);
                }
                Console.WriteLine("数据源:");
                foreach (var item in x) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                Console.WriteLine("二叉堆排序:");
                foreach (var item in bh.Sort()) {
                    Console.Write("{0} ", item);
                }
            }
        }
    }
    /*引用的特性*/
    namespace Test4 {
        class A {
            public int a;
        }
        [TestClass]
        public class MyTestClass {
            /*测试名称: 	MyTestMethod
                测试结果: 	已通过
                结果 的标准输出: 	
                a2.a=55
                a2.a=55
             */
            [TestMethod]
            public void MyTestMethod() {
                var a1 = new A();
                a1.a = 55;
                var a2 = a1;
                Console.WriteLine("a2.a={0}", a2.a);
                a1 = null;
                Console.WriteLine("a2.a={0}", a2.a);
            }
        }
    }
    /*virtual override 有什么用？*/
    namespace Test3 {
        //为什么 C# 需要 virtual 和override呢？ 不要也不是一样？
        class A {
            public virtual void M() {
                Console.WriteLine("A.M");
            }
            public void M2() {
                Console.WriteLine("A.M2");
            }
            public void Show() {
                M();
            }
            public void Show2() {
                M2();
            }
        }
        class B : A {
            public override void M() {
                Console.WriteLine("B.M");
            }
            public new void M2() {
                Console.WriteLine("B.M2");
            }
        }
        class C : A {
            public override void M() {
                Console.WriteLine("C.M");
            }
            public new void M2() {
                Console.WriteLine("C.M2");
            }
        }

        //有毛区别啊
        class E {
            public void F() { Console.WriteLine("E.F"); }
            public virtual void G() { Console.WriteLine("E.G"); }
        }
        class K : E {
            new public void F() { Console.WriteLine("K.F"); }
            public override void G() { Console.WriteLine("K.G"); }
        }
        [TestClass]
        public class Test12 {
            /*测试名称: 	Main1
                测试结果: 	已通过
                结果 的标准输出: 	
                a.F()=E.F
                b.F()=K.F
                ab.F()=E.F
                a.G()=E.G
                b.G()=K.G
                ab.G()=K.G
             * */
            [TestMethod]
            public void Main1() {
                K b = new K();
                E ab = b;//这里a的类型是B类对象
                E a = new E();
                Console.Write("a.F()="); a.F();
                Console.Write("b.F()="); b.F();
                Console.Write("ab.F()="); ab.F();
                Console.Write("a.G()="); a.G();
                Console.Write("b.G()="); b.G();
                Console.Write("ab.G()="); ab.G();
            }
        }
        [TestClass]
        public class Test11 {
            [TestMethod]
            public void Test112() {
                var b = new B();
                b.Show();
                b.Show2();
                var c = new C();
                c.Show();
                c.Show2();
            }
            [TestMethod]
            public void Test111() {
                var a = new A();
                a.M();
                a.M2();
                var b = new B();
                b.M();
                b.M2();
            }
        }

    }
    /*razor engine RezorCodeDomSample*/
    namespace Test2 {
        [TestClass]
        public class Program {
            [TestMethod]
            public void Main1() {
                //簡單的範本	
                string template = @"@{var name=""Would"";}
                                Hello @name!!";
                var input = new System.IO.StringReader(template);

                //產生Razor的TemplateEngine
                var host = new RazorEngineHost(new CSharpRazorCodeLanguage());
                host.DefaultBaseClass = "RezorCodeDomSample.MyTemplate";
                host.DefaultNamespace = "RezorCodeDomSample";
                host.DefaultClassName = "MyTemplateResult";
                var engine = new RazorTemplateEngine(host);

                //取得結果的CodeDom
                var code = engine.GenerateCode(input);
                var codeType = code.GeneratedCode.Namespaces[0].Types[0];
                var codeProvider = new CSharpCodeProvider();

                //將CodeDom輸出到檔案中
                //CodeGeneratorOptions options = new CodeGeneratorOptions();
                //options.BlankLinesBetweenMembers = true;
                //System.IO.StringWriter sw = new System.IO.StringWriter();
                //codeProvider.GenerateCodeFromCompileUnit(code.GeneratedCode, sw, options);
                //File.WriteAllText("c:\\text.cs", sw.ToString());

                //將CodeDom編譯
                var options = new CompilerParameters() {
                    GenerateInMemory = true,
                    GenerateExecutable = false,
                };
                options.ReferencedAssemblies.Add(typeof(Program).Assembly.Location);
                var asselby = codeProvider.CompileAssemblyFromDom(options, code.GeneratedCode);

                //執行Template
                var type = asselby.CompiledAssembly.GetType("RezorCodeDomSample.MyTemplateResult");
                var ins = Activator.CreateInstance(type) as MyTemplate;
                ins.Execute();
                Console.Write(ins.Reault);
            }
        }

        //如果沒有Base類會不好處理
        public class MyTemplate {
            private StringBuilder sb = new StringBuilder();

            public virtual void Execute() {
            }

            public void Write(object value) {
                sb.Append(value);
            }

            public void WriteLiteral(object value) {
                sb.Append(value);
            }

            public string Reault {
                get { return sb.ToString(); }
            }
        }
    }
    /*string test*/
    namespace Test1 {
        [TestClass]
        public class MyTestClass {
            [TestMethod]
            public void Test25() {
                var x = 10.AdagunSet();
                var y = x.Filter(i => i * 2.5);
                foreach (var item in y) {
                    Console.WriteLine(item);
                }
            }
            [TestMethod]
            public void Test24() {
                var x = new int[1];
                x[0] = 5;
                x[0] = x[0] ^ x[0];
                x[0] = x[0] ^ x[0];
                x[0] = x[0] ^ x[0];
                Console.WriteLine(x[0]);
                var x2 = 5;
                x2 = x2 ^ x2;
                x2 = x2 ^ x2;
                x2 = x2 ^ x2;
                Console.WriteLine(x2);
            }
            [TestMethod]
            public void Test23() {
                int i, j;
                i = 2; j = 2;
                Console.WriteLine("i={0},j={1}", i, j);
                i = i ^ j;
                j = i ^ j;
                i = i ^ j;
                Console.WriteLine("i={0},j={1}", i, j);
            }
            [TestMethod]
            public void Test22() {
                var x = 12.AdagunSet().ToArray();
                foreach (var item in x) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                Console.WriteLine("----------------洗牌算法----------------");
                x.Shuffle();
                foreach (var item in x) {
                    Console.Write("{0} ", item);
                }
                Console.WriteLine();
                Console.WriteLine("----------------鸡尾酒排序----------------");
                x.SortCocktail();
                foreach (var item in x) {
                    Console.Write("{0} ", item);
                }
            }
            [TestMethod]
            public void MyTestMethod() {
                var teststring1 = "a;lsdkfj159lkdfjh=-76p[dk1234056=-=26798js9qwp'w";
                var teststring2 = "kdfja;lsdkf76p[dk12j159lh=-34w98j056=-s9qp=267'w";
                Console.WriteLine(teststring1.CheckMatch(teststring2));
            }
            [TestMethod]
            public void M2() {//测试字串相减
                var a = "adfafafd11250*kk";
                var b = "50*kk";
                Console.WriteLine(a);
                Console.WriteLine(b);
                Console.WriteLine(a.Subtract(b));
            }
            [TestMethod]
            public void m11() {
                var x = "12:00:35,2015-02-27T10:00:05";
                var x2 = x.ToTypeValues<DateTime>(',');
                foreach (var item in x2) {
                    Console.WriteLine(item);
                }
            }
        }
    }
    namespace FinderTreeTest {
        class Tnode : IComparable<Tnode> {
            public string value;
            public int key;
            public int CompareTo(Tnode other) {
                return key - other.key;
            }
        }

        [TestClass]
        public class MyTestClass {
            [TestMethod]
            public void MyTestMethod2() {
                ushort x = 12;
                var x2 = x.UnrepeatSet(50).ToArray();
                var ft = new BinFinderTree<int>();
                ft.LoadData(x2);
                for (int i = 0; i < ft.Count; i++) {
                    Console.WriteLine(ft[i].Data);
                    Console.WriteLine("item path is {0}", ft.GetPath(ft[i]) ?? "root");
                }
            }
            [TestMethod]
            public void MyTestMethod() {
                ushort x = 12;
                var x2 = x.UnrepeatSet(50).ToArray();
                var ft = new BinFinderTree<int>();
                ft.LoadData(x2);
                var x3 = ft.GetPath(x2[5]);
                var x4 = ft[5];
                var x5 = ft.GetPath(x4);

                Console.WriteLine("x2[5]={0}", x2[5]);
                Console.WriteLine("ft[5]={0}", x4.Data);
                Console.WriteLine("ft[5] path is {0}", x5);
                Console.WriteLine("Max={0}", ft.Max);
                Console.WriteLine("Min={0}", ft.Min);
                foreach (var item in x2) {
                    Console.WriteLine(item);
                }
                foreach (var item in x3) {
                    Console.WriteLine("path is {0}", item);
                }
            }
            [TestMethod]
            public void FinderTreeTest1() {
                ushort x = 12;
                var x2 = x.UnrepeatSet(50);
                var ft = new BinFinderTree<int>();
                ft.LoadData(x2);
                Console.WriteLine(ft.Count);
                Console.WriteLine("----------------------------------------");
                var x3 = ft.Query(i => i > 25);
                foreach (var item in x3) {
                    Console.WriteLine(item);
                }
                Console.WriteLine("----------------------------------------");
                Console.WriteLine(ft.Max);
                Console.WriteLine(ft.Min);
            }
        }
    }
    /*others*/
    namespace Test2 {
        [TestClass]
        public class MyTestClass {
            [TestMethod]
            public void M1() {
                var path = @"C:\Users\Public\Pictures\Sample Pictures\juhua.jpg";
                var path2 = @"E:\tfs\tfs29\CompoentFactory\UnitTestProject1\youtobe.jpg";
                File.Open(path, FileMode.Open).CopyStreamTo(File.Open(path2, FileMode.OpenOrCreate, FileAccess.Write));
                Console.WriteLine("copy completed!");
            }
        }
    }
}

